/*  Copyright (c) 2012 William Rogers and James Boud

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

using SlimDX;
using SlimDX.Direct3D11;
using System;
using BlendState = SlimDX.Direct3D11.BlendState;
using Microsoft.Xna.Framework.Content;
using JBBRXG11ContentTexture;

namespace JBBRXG11
{
    public sealed class RenderState
    {
        // Lots of guessing about the index parameters for BlendEnable and WriteChannels
        // Seem to remember something about DX10 permitting separate control for each
        // render target - but it is all blurry, and this doesn't make much sense here
        GraphicsDevice device;
        

        BlendStateDescription defaultbsdesc, bsdesc;
        SlimDX.Direct3D11.BlendState lastusedbs;  // Keep track for disposal
        bool bsdesc_changed;
        internal void CopyFromCurrentBlendState(ref BlendStateDescription dest)
        {
            blendstatecopy(bsdesc, ref dest);
        }
        internal void CopyToCurrentBlendState(ref BlendStateDescription source)
        {
            blendstatecopy(source, ref bsdesc);
            bsdesc_changed = true;
        }
        internal void CopyFromDefaultBlendState(ref BlendStateDescription dest)
        {
            blendstatecopy(defaultbsdesc, ref dest);
        }

        Color4 blend_factor;
        bool blend_factor_changed;

        DepthStencilStateDescription defaultdssdesc, dssdesc;
        DepthStencilOperationDescription dssbackdesc, dssfrontdesc;
        SlimDX.Direct3D11.DepthStencilState lastuseddss;
        bool dssdesc_changed;
        internal DepthStencilStateDescription CurrentDepthStencilState
        {
            get
            {
                dssdesc.BackFace = dssbackdesc;
                dssdesc.FrontFace = dssfrontdesc;
                return dssdesc;
            }
            set
            {
                dssdesc = value;
                dssbackdesc = dssdesc.BackFace;
                dssfrontdesc = dssdesc.FrontFace;
                dssdesc_changed = true;
            }
        }
        internal DepthStencilStateDescription DefaultDepthStencilState { get { return defaultdssdesc; } }

        int depth_stencil_reference;
        bool depth_stencil_reference_changed;
        bool twosidedstencilmode;  // Not doing anything with this currently

        RasterizerStateDescription rsdesc;
        SlimDX.Direct3D11.RasterizerState lastusedrs;
        bool rsdesc_changed;

        public void ApplyUpdates()
        {
            if (bsdesc_changed)
            {
                if (lastusedbs != null) lastusedbs.Dispose();
                lastusedbs = SlimDX.Direct3D11.BlendState.FromDescription(device.DX_Device, bsdesc);
                device.DX_Device_Context.OutputMerger.BlendState = lastusedbs;
                bsdesc_changed = false;
            }
            if (blend_factor_changed)
            {
                device.DX_Device_Context.OutputMerger.BlendFactor = blend_factor;
                blend_factor_changed = false;
            }
            if (dssdesc_changed)
            {
                dssdesc.BackFace = dssbackdesc;
                dssdesc.FrontFace = dssfrontdesc;
                if (lastuseddss != null) lastuseddss.Dispose();
                lastuseddss = SlimDX.Direct3D11.DepthStencilState.FromDescription(device.DX_Device, dssdesc);
                device.DX_Device_Context.OutputMerger.DepthStencilState = lastuseddss;
                dssdesc_changed = false;
            }
            if (depth_stencil_reference_changed)
            {
                device.DX_Device_Context.OutputMerger.DepthStencilReference = depth_stencil_reference;
                depth_stencil_reference_changed = false;
            }
            if (rsdesc_changed)
            {
                if (lastusedrs != null) lastusedrs.Dispose();
                lastusedrs = SlimDX.Direct3D11.RasterizerState.FromDescription(device.DX_Device, rsdesc);
                device.DX_Device_Context.Rasterizer.State = lastusedrs;
                rsdesc_changed = false;
            }
        }

        #region Blend State
        public bool AlphaBlendEnable
        {
            get { return bsdesc.RenderTargets[0].BlendEnable; }
            set
            {
                bsdesc.RenderTargets[0].BlendEnable = value;
                bsdesc.RenderTargets[1].BlendEnable = value;
                bsdesc.RenderTargets[2].BlendEnable = value;
                bsdesc.RenderTargets[3].BlendEnable = value;
                bsdesc_changed = true;
            }
        }

        public Microsoft.Xna.Framework.Graphics.BlendFunction AlphaBlendOperation
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].BlendOperationAlpha); }
            set { bsdesc.RenderTargets[0].BlendOperationAlpha = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.Blend AlphaDestinationBlend
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].DestinationBlendAlpha); }
            set { bsdesc.RenderTargets[0].DestinationBlendAlpha = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.Blend AlphaSourceBlend
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].SourceBlendAlpha); }
            set { bsdesc.RenderTargets[0].SourceBlendAlpha = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.BlendFunction BlendFunction
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].BlendOperation); }
            set { bsdesc.RenderTargets[0].BlendOperation = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.Blend DestinationBlend
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].DestinationBlend); }
            set { bsdesc.RenderTargets[0].DestinationBlend = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.Blend SourceBlend
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].SourceBlend); }
            set { bsdesc.RenderTargets[0].SourceBlend = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.ColorWriteChannels ColorWriteChannels
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[0].RenderTargetWriteMask); }
            set { bsdesc.RenderTargets[0].RenderTargetWriteMask = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.ColorWriteChannels ColorWriteChannels1
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[1].RenderTargetWriteMask); }
            set { bsdesc.RenderTargets[1].RenderTargetWriteMask = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.ColorWriteChannels ColorWriteChannels2
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[2].RenderTargetWriteMask); }
            set { bsdesc.RenderTargets[2].RenderTargetWriteMask = EnumConversions.convert(value); bsdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.ColorWriteChannels ColorWriteChannels3
        {
            get { return EnumConversions.convert(bsdesc.RenderTargets[3].RenderTargetWriteMask); }
            set { bsdesc.RenderTargets[3].RenderTargetWriteMask = EnumConversions.convert(value); bsdesc_changed = true; }
        }
        #endregion

        public Microsoft.Xna.Framework.Color BlendFactor
        {
            get { return EnumConversions.convert(blend_factor); }
            set { blend_factor = EnumConversions.convert(value); blend_factor_changed = true; }
        }

        #region Depth Stencil State

        public bool DepthBufferEnable
        {
            get { return dssdesc.IsDepthEnabled; }
            set { dssdesc.IsDepthEnabled = value; dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.CompareFunction DepthBufferFunction
        {
            get { return EnumConversions.convert(dssdesc.DepthComparison); }
            set { dssdesc.DepthComparison = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public bool DepthBufferWriteEnable
        {
            get { return (dssdesc.DepthWriteMask == DepthWriteMask.All); }
            set { dssdesc.DepthWriteMask = (value ? DepthWriteMask.All : DepthWriteMask.Zero); dssdesc_changed = true; }
        }

        // The names of the fields suggest a change of semantics between
        // XNA and DX10 - in that the clockwise and counterclockwise 
        // settings should be flipped when the cull mode changes
        public bool StencilEnable
        {
            get { return dssdesc.IsStencilEnabled; }
            set { dssdesc.IsStencilEnabled = value; dssdesc_changed = true; }
        }

        public int StencilMask
        {
            get { return (int)dssdesc.StencilReadMask; }
            set { dssdesc.StencilReadMask = (byte)(value & 255); dssdesc_changed = true; }
        }

        public int StencilWriteMask
        {
            get { return (int)dssdesc.StencilWriteMask; }
            set { dssdesc.StencilWriteMask = (byte)(value & 255); dssdesc_changed = true; }
        }

        public bool TwoSidedStencilMode
        {
            // I'm guessing that this isn't used in DX10, so I can
            // emulate it by writing into both clockwise and counterclockwise
            // settings when it is false.  For the moment, just record the flag
            // TODO: Look into this
            get { return twosidedstencilmode; }
            set { twosidedstencilmode = value; }
        }

        public Microsoft.Xna.Framework.Graphics.StencilOperation CounterClockwiseStencilDepthBufferFail
        {
            get { return EnumConversions.convert(dssbackdesc.DepthFailOperation); }
            set { dssbackdesc.DepthFailOperation = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.StencilOperation StencilDepthBufferFail
        {
            get { return EnumConversions.convert(dssfrontdesc.DepthFailOperation); }
            set { dssfrontdesc.DepthFailOperation = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.StencilOperation CounterClockwiseStencilFail
        {
            get { return EnumConversions.convert(dssbackdesc.FailOperation); }
            set { dssbackdesc.FailOperation = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.StencilOperation StencilFail
        {
            get { return EnumConversions.convert(dssfrontdesc.FailOperation); }
            set { dssfrontdesc.FailOperation = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.StencilOperation CounterClockwiseStencilPass
        {
            get { return EnumConversions.convert(dssbackdesc.PassOperation); }
            set { dssbackdesc.PassOperation = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.StencilOperation StencilPass
        {
            get { return EnumConversions.convert(dssfrontdesc.PassOperation); }
            set { dssfrontdesc.PassOperation = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.CompareFunction CounterClockwiseStencilFunction
        {
            get { return EnumConversions.convert(dssbackdesc.Comparison); }
            set { dssbackdesc.Comparison = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        public Microsoft.Xna.Framework.Graphics.CompareFunction StencilFunction
        {
            get { return EnumConversions.convert(dssfrontdesc.Comparison); }
            set { dssfrontdesc.Comparison = EnumConversions.convert(value); dssdesc_changed = true; }
        }

        #endregion

        public int ReferenceStencil
        {
            get { return depth_stencil_reference; }
            set { depth_stencil_reference = value; depth_stencil_reference_changed = true; }
        }

        #region Rasterizer State
        public Microsoft.Xna.Framework.Graphics.FillMode FillMode
        {
            get
            {
                if (rsdesc.FillMode == SlimDX.Direct3D11.FillMode.Solid)
                    return Microsoft.Xna.Framework.Graphics.FillMode.Solid;
                else
                    return Microsoft.Xna.Framework.Graphics.FillMode.WireFrame;
            }
            set
            {
                if (value == Microsoft.Xna.Framework.Graphics.FillMode.Solid)
                    rsdesc.FillMode = SlimDX.Direct3D11.FillMode.Solid;
                else if (value == Microsoft.Xna.Framework.Graphics.FillMode.WireFrame)
                    rsdesc.FillMode = SlimDX.Direct3D11.FillMode.Wireframe;
                else
                    throw new Exception("JBBRXG11 error: DirectX 10 does not support FillMode.Point");
                rsdesc_changed = true;
            }
        }

        public Microsoft.Xna.Framework.Graphics.CullMode CullMode
        {
            get
            {
                if (rsdesc.CullMode == SlimDX.Direct3D11.CullMode.Back)
                    return Microsoft.Xna.Framework.Graphics.CullMode.CullCounterClockwiseFace;
                else if (rsdesc.CullMode == SlimDX.Direct3D11.CullMode.Front)
                    return Microsoft.Xna.Framework.Graphics.CullMode.CullClockwiseFace;
                else
                    return Microsoft.Xna.Framework.Graphics.CullMode.None;
            }
            set
            {
                if (value == Microsoft.Xna.Framework.Graphics.CullMode.CullCounterClockwiseFace)
                    rsdesc.CullMode = SlimDX.Direct3D11.CullMode.Back;
                else if (value == Microsoft.Xna.Framework.Graphics.CullMode.CullClockwiseFace)
                    rsdesc.CullMode = SlimDX.Direct3D11.CullMode.Front;
                else
                    rsdesc.CullMode = SlimDX.Direct3D11.CullMode.None;
                rsdesc_changed = true;
            }
        }

        public float DepthBias
        {
            get { return (float)rsdesc.DepthBias; }
            set { rsdesc.DepthBias = (int)value; rsdesc_changed = true; }
        }

        public bool ScissorTestEnable
        {
            get { return rsdesc.IsScissorEnabled; }
            set { rsdesc.IsScissorEnabled = value; rsdesc_changed = true; }
        }
        #endregion

        void blendstatecopy(BlendStateDescription source, ref BlendStateDescription dest)
        {
            dest.RenderTargets[0].BlendEnable = source.RenderTargets[0].BlendEnable;
            dest.RenderTargets[1].BlendEnable = source.RenderTargets[1].BlendEnable;
            dest.RenderTargets[2].BlendEnable = source.RenderTargets[2].BlendEnable;
            dest.RenderTargets[3].BlendEnable = source.RenderTargets[3].BlendEnable;
            dest.RenderTargets[4].BlendEnable = source.RenderTargets[4].BlendEnable;
            dest.RenderTargets[5].BlendEnable = source.RenderTargets[5].BlendEnable;
            dest.RenderTargets[6].BlendEnable = source.RenderTargets[6].BlendEnable;
            dest.RenderTargets[7].BlendEnable = source.RenderTargets[7].BlendEnable;
            dest.RenderTargets[0].BlendOperationAlpha = source.RenderTargets[0].BlendOperationAlpha;
            dest.RenderTargets[0].DestinationBlendAlpha = source.RenderTargets[0].DestinationBlendAlpha;
            dest.RenderTargets[0].SourceBlendAlpha = source.RenderTargets[0].SourceBlendAlpha;
            dest.RenderTargets[0].BlendOperation = source.RenderTargets[0].BlendOperation;
            dest.RenderTargets[0].DestinationBlend = source.RenderTargets[0].DestinationBlend;
            dest.RenderTargets[0].SourceBlend = source.RenderTargets[0].SourceBlend;
            //  IsAlphaToCoverageEnabled   --- Find out what this means (meant)
            dest.RenderTargets[0].RenderTargetWriteMask = source.RenderTargets[0].RenderTargetWriteMask;
            dest.RenderTargets[1].RenderTargetWriteMask = source.RenderTargets[1].RenderTargetWriteMask;
            dest.RenderTargets[2].RenderTargetWriteMask = source.RenderTargets[2].RenderTargetWriteMask;
            dest.RenderTargets[3].RenderTargetWriteMask = source.RenderTargets[3].RenderTargetWriteMask;
            dest.RenderTargets[4].RenderTargetWriteMask = source.RenderTargets[4].RenderTargetWriteMask;
            dest.RenderTargets[5].RenderTargetWriteMask = source.RenderTargets[5].RenderTargetWriteMask;
            dest.RenderTargets[6].RenderTargetWriteMask = source.RenderTargets[6].RenderTargetWriteMask;
            dest.RenderTargets[7].RenderTargetWriteMask = source.RenderTargets[7].RenderTargetWriteMask;
        }

        // Constructor
        internal RenderState(GraphicsDevice dev)
        {
            device = dev;

            #region Blend State
            bsdesc_changed = true;  // To enforce our defaults??
            lastusedbs = null;
            bsdesc = new BlendStateDescription();
            bsdesc.RenderTargets[0].BlendEnable = false;
            bsdesc.RenderTargets[1].BlendEnable = false;
            bsdesc.RenderTargets[2].BlendEnable = false;
            bsdesc.RenderTargets[3].BlendEnable = false;
            bsdesc.RenderTargets[4].BlendEnable = false;
            bsdesc.RenderTargets[5].BlendEnable = false;
            bsdesc.RenderTargets[6].BlendEnable = false;
            bsdesc.RenderTargets[7].BlendEnable = false;
            bsdesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add;
            bsdesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero;
            bsdesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One;
            bsdesc.RenderTargets[0].BlendOperation = BlendOperation.Add;
            bsdesc.RenderTargets[0].DestinationBlend = BlendOption.Zero;
            bsdesc.RenderTargets[0].SourceBlend = BlendOption.One;
            //bds.IsAlphaToCoverageEnabled   // Find out what this means (meant)
            bsdesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;  // Documented as defaulting to None???
            bsdesc.RenderTargets[1].RenderTargetWriteMask = 0;
            bsdesc.RenderTargets[2].RenderTargetWriteMask = 0;
            bsdesc.RenderTargets[3].RenderTargetWriteMask = 0;
            bsdesc.RenderTargets[4].RenderTargetWriteMask = 0;
            bsdesc.RenderTargets[5].RenderTargetWriteMask = 0;
            bsdesc.RenderTargets[6].RenderTargetWriteMask = 0; //TODO: Why was it 7 before?
            bsdesc.RenderTargets[7].RenderTargetWriteMask = 0;
            // Don't copy blendstatedescriptions - the array
            // of blend enable booleans has its pointer copied
            // and then shared and ... In other words it doesn't
            // behave like a nice structure wrt copying
            // Have done no experiments, but probably the write
            // mask array? is similar
            defaultbsdesc = new BlendStateDescription();
            blendstatecopy(bsdesc, ref defaultbsdesc);
            #endregion

            // Blend Factor
            blend_factor_changed = true;
            blend_factor = new Color4(1, 1, 1, 1);  // White

            #region Depth Stencil State
            dssdesc_changed = true;
            lastuseddss = null;
            dssdesc.DepthComparison = Comparison.Less;
            dssdesc.DepthWriteMask = DepthWriteMask.All;
            dssdesc.IsDepthEnabled = true;
            dssdesc.IsStencilEnabled = false;
            dssdesc.StencilReadMask = (byte)255;
            dssdesc.StencilWriteMask = (byte)255;
            dssbackdesc = new DepthStencilOperationDescription();
            dssbackdesc.Comparison = Comparison.Always;
            dssbackdesc.DepthFailOperation = StencilOperation.Keep;
            dssbackdesc.FailOperation = StencilOperation.Keep;
            dssbackdesc.PassOperation = StencilOperation.Keep;
            dssfrontdesc = dssbackdesc;
            twosidedstencilmode = false;

            defaultdssdesc = dssdesc;
            defaultdssdesc.BackFace = dssbackdesc;
            defaultdssdesc.FrontFace = dssfrontdesc;
            #endregion

            // Depth Stencil Reference
            depth_stencil_reference_changed = true;
            depth_stencil_reference = 0;

            #region Rasterizer State
            rsdesc_changed = true;
            lastusedrs = null;
            rsdesc.FillMode = SlimDX.Direct3D11.FillMode.Solid;
            rsdesc.CullMode = SlimDX.Direct3D11.CullMode.Back;
            rsdesc.IsFrontCounterclockwise = false;
            rsdesc.DepthBias = 0;
            rsdesc.DepthBiasClamp = 0;
            rsdesc.SlopeScaledDepthBias = 0;
            rsdesc.IsDepthClipEnabled = true;
            rsdesc.IsScissorEnabled = false;
            rsdesc.IsMultisampleEnabled = false;
            rsdesc.IsAntialiasedLineEnabled = false;
            #endregion
        }

        internal void Dispose()
        {
            if (lastusedbs != null)
                lastusedbs.Dispose();
            if (lastuseddss != null)
                lastuseddss.Dispose();
            if (lastusedrs != null)
                lastusedrs.Dispose();
        }
    }
}

/*
        //
        // Summary:
        //     Gets or sets the comparison function for the alpha test. The default is CompareFunction.Always.
        public CompareFunction AlphaFunction { get { } set { } }
        //
        // Summary:
        //     Gets or sets a render state that enables a per-pixel alpha test. The default
        //     value is false.
        public bool AlphaTestEnable { get { } set { } }
        //
 * 
 * 
        //
        // Summary:
        //     Gets or sets the fog color. The default value is Color.TransparentBlack.
        public Color FogColor { get { } set { } }
        //
        // Summary:
        //     Gets or sets the fog density for pixel or vertex fog used in exponential
        //     fog modes. The default value is 1.0f.
        public float FogDensity { get { } set { } }
        //
        // Summary:
        //     Enables or disables fog blending. The default is false.
        public bool FogEnable { get { } set { } }
        //
        // Summary:
        //     Gets or sets the depth at which pixel or vertex fog effects end for linear
        //     fog mode. The default value is 1.0f.
        public float FogEnd { get { } set { } }
        //
        // Summary:
        //     Gets or sets the depth at which pixel or vertex fog effects begin for linear
        //     fog mode. The default value is 0.0f.
        public float FogStart { get { } set { } }
        //
        // Summary:
        //     Gets or sets the fog formula to use for pixel fog. The default is None.
        public FogMode FogTableMode { get { } set { } }
        //
        // Summary:
        //     Gets or sets the fog formula to use for vertex fog. The default is FogMode.None.
        public FogMode FogVertexMode { get { } set { } }
        //
        // Summary:
        //     Enables or disables multisample antialiasing. The default is true.
        public bool MultiSampleAntiAlias { get { } set { } }
        //
        // Summary:
        //     Gets or sets a bitmask controlling modification of the samples in a multisample
        //     render target. The default is 0xffffffff.
        public int MultiSampleMask { get { } set { } }
        //
        // Summary:
        //     Gets or sets the size to use for point size computation in cases where point
        //     size is not specified for each vertex. The default value is the value a driver
        //     returns. If a driver returns 0 or 1, the default value is 64, which allows
        //     software point size emulation. Reference page contains links to related code
        //     samples.
        public float PointSize { get { } set { } }
        //
        // Summary:
        //     Gets or sets the maximum size of point primitives. The default is 64.0f.
        public float PointSizeMax { get { } set { } }
        //
        // Summary:
        //     Gets or sets the minimum size of point primitives. The default is 1.0f.
        public float PointSizeMin { get { } set { } }
        //
        // Summary:
        //     Enables or disables full texture mapping on each point. The default is false.
        //     Reference page contains links to related code samples.
        public bool PointSpriteEnable { get { } set { } }
        //
        // Summary:
        //     Gets or sets enabling of range-based vertex fog. The default value is false.
        public bool RangeFogEnable { get { } set { } }
        //
        // Summary:
        //     Specifies a reference alpha value against which pixels are tested when alpha
        //     testing is enabled. The default value is 0.
        public int ReferenceAlpha { get { } set { } }

        //
        // Summary:
        //     Enables or disables the separate blend mode for the alpha channel. The default
        //     is false.
        public bool SeparateAlphaBlendEnabled { get { } set { } }
        //
        // Summary:
        //     Gets or sets a value used to determine how much bias can be applied to coplanar
        //     primitives to reduce flimmering z-fighting. The default is 0.
        public float SlopeScaleDepthBias { get { } set { } }

        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap0 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap1 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap10 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap11 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap12 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap13 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap14 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap15 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap2 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap3 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap4 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap5 { get { } set { } }
        //
        // Summary:
        //     Gets or sets the texture-wrapping behavior for multiple sets of texture coordinates.
        //     The default value for this render state is TextureWrapCoordinates.Zero (wrapping
        //     disabled in all directions). Reference page contains links to related conceptual
        //     articles.
        public TextureWrapCoordinates Wrap6 { get { } set { } }
        //
        // 
dss = null;
            dssdesc.DepthComparison = Comparison.Less;
            dssdesc.DepthWriteMask = DepthWriteMask.All;
            dssdesc.IsDepthEnabled = true;
            dssdesc.IsStencilEnabled = false;
            dssdesc.StencilReadMask = (byte)255;
            dssdesc.StencilWriteMask = (byte)255;
            dssbackdesc = new DepthStencilOperationDescription();
            dssbackdesc.Comparison = Comparison.Always;
            dssbackdesc.DepthFailOperation = StencilOperation.Keep;
            dssbackdesc.FailOperation = StencilOperation.Keep;
            dssbackdesc.PassOperation = StencilOperation.Keep;
            dssfrontdesc = dssbackdesc;
            twosidedstencilmode = false;

            defaultdssdesc = dssdesc;
            defaultdssdesc.BackFace = dssbackdesc;
            defaultdssdesc.FrontFace = dssfrontdesc;
            #endregion

            // Depth Stencil Reference
            depth_stencil_reference_changed = true;
            depth_stencil_reference = 0;

            #region Rasterizer State
            rsdesc_changed = true;
            lastusedrs = null;
            rsdesc.FillMode = SlimDX.Direct3D11.FillMode.Solid;
            rsdesc.CullMode = SlimDX.Direct3D11.CullMode.Back;
            rsdesc.IsFrontCounterclockwise = false;
            rsdesc.DepthBias = 0;
            rsdesc.D﻿using System;
*/
